#!/usr/bin/python3
# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: t -*-

import os
import subprocess
from gi.repository import GLib
from fm_param import FmConst
from usr_session_common import UsrSessionHelperBase, PipeWire, WayFireInstance


class UsrSessionHelperGui(UsrSessionHelperBase):

    """
    notes:
        * sub-modules should use XDG_SEAT environment variables to know which seat we are on
    """

    def __init__(self, parent, session_id, **kwargs):
        super().__init__(parent, session_id)

        self._tmpDir = FmConst.getTmpDir(self._sessionId)
        os.makedirs(self._tmpDir, exist_ok=True)

        self._pwObj = None
        self._wayfireObj = None
        self._bgProc = None
        self._imfProc = None
        self._panelProc = None
        self._wirePlumberProc = None

    def start(self, machine):
        envDict = os.environ.copy()
        try:
            self._pwObj = PipeWire(self._sessionId)

            self._wayfireObj = WayFireInstance(self._sessionId, os.path.join(self._tmpDir, "wayfire.ini"), machine, "fcitx", "pipewire", False)
            assert all([x not in os.environ for x in self._wayfireObj.envDict])
            envDict.update(self._wayfireObj.envDict)

            command = ["wf-background"]
            self._bgProc = subprocess.Popen(command, env=envDict)

            ret = self._startImf(envDict)
            assert all([x not in os.environ for x in ret])
            envDict.update(ret)

            command = ["wf-panel"]
            self._panelProc = subprocess.Popen(command, env=envDict)

            # FIXME: managers, to be replaced
            command = ["wireplumber"]
            self._wirePlumberProc = subprocess.Popen(command)
        except BaseException:
            self.exit()
            raise

    def exit(self):
        if self._wirePlumberProc is not None:
            self._wirePlumberProc.terminate()
            self._wirePlumberProc.wait()
            self._wirePlumberProc = None
        if self._panelProc is not None:
            self._panelProc.terminate()
            self._panelProc.wait()
            self._panelProc = None
        if self._imfProc is not None:
            self._imfProc.terminate()
            self._imfProc.wait()
            self._imfProc = None
        if self._bgProc is not None:
            self._bgProc.terminate()
            self._bgProc.wait()
            self._bgProc = None
        if self._wayfireObj is not None:
            self._wayfireObj.dispose()
            self._wayfireObj = None
        if self._pwObj is not None:
            self._pwObj.dispose()
            self._pwObj = None

    def _startImf(self, envDict):
        command = ["fcitx5"]
        self._imfProc = subprocess.Popen(command, env=envDict)
        return {
            "GTK_IM_MODULE": "fcitx",
            "QT_IM_MODULE": "fcitx",
            "SDL_IM_MODULE": "fcitx",       # FIXME: does this really needed?
            "GLFW_IM_MODULE": "ibus",       # note: kitty uses this environment variable, it only supports ibus, fcitx also exports ibus interface so it's ok
        }

    def _callback(self, pid, status):
        GLib.spawn_check_wait_status(status)
